package ext.tianma.bom.workflow;

import java.rmi.RemoteException;
import java.util.ArrayList;
import ext.tianma.part.forms.TMTypeUtil;
import wt.doc.WTDocument;
import wt.fc.QueryResult;
import wt.fc.WTObject;
import wt.fc.collections.WTArrayList;
import wt.lifecycle.LifeCycleManaged;
import wt.part.WTPart;
import wt.util.WTException;
import wt.vc.wip.WorkInProgressHelper;
import wt.workflow.engine.WfProcess;
import wt.workflow.engine.WfState;
import ext.com.iba.IBAUtil;
import ext.tianma.version.ComToolUtil;
import wt.type.ClientTypedUtility;
/**Description:【设计转量产流程】的业务逻辑 2013-09-18确认
 * @author    :  YangWen
 * @create at :  2013-9-22   上午9:57:28
 */
public class ConversionThroughputBusiness implements BOMWorkFlowInterface{
	
	/**
	 * 展示是否输出log信息
	 */
	private static boolean isShow = true;
	
	/**
     * 成品
     */
    private static final String FINISHEDGOOD = SingletonBOM.getInstance().getFinishedGood();
    
    /**生命周期状态数组
	 * NewProduct.value=新品
	 * TrialProduction.value=试产
	 */
	private static final String[] LIFESTATEARRAY = { "NewProduct","TrialProduction","RiskOrder","CustomerSample" };
	
	
	/**
	 * 私有构造函数，防止实例化
	 */
	private ConversionThroughputBusiness(){
		
	}
	
	

	/**输出log信息
	 * @param info
	 */
	private static void out(String info){
		if(isShow)
			System.out.println("【设计转量产流程】的业务处理逻辑:"+ConversionThroughputBusiness.class.getName()+":"+info);
	}
	
	
	
	/**YW
	 * 展示页面数据
	 * @param pbo 业务主对象
	 * @param reviewObjs 随签列表
	 * @param tableData 不符合要求列表
	 * @throws WTException 
	 */
	public static void showPageData(WTObject pbo , WTArrayList reviewObjs , ArrayList<WTPart>  tableData) throws WTException{		
    	if(pbo == null || !(pbo instanceof WTDocument)){
    		out("传入进来的对象"+pbo+"为空或者不是【WTDocument】类型的对象，直接返回空！");
    		return ;
    	}
    	
    	ArrayList<WTPart> allPart = new ArrayList<WTPart>();
    	
	    WTDocument doc = (WTDocument) pbo;
	    //获取当前文档所关联的所有零部件
	    QueryResult refPartQR = ext.com.core.CoreUtil.getAssociatedParts(doc);
	    while (refPartQR.hasMoreElements()) {
			Object refObj = refPartQR.nextElement();
			if (refObj instanceof WTPart) {
			    WTPart part = (WTPart) refObj;
			 	//递归获得所有的子部件
		    	ArrayList<WTPart> allSubPart = BOMBusinessUtil.getAllSubPart(part);
		    	out("指定对象【"+part.getDisplayIdentifier()+"】下包含的所有子部件个数是："+allSubPart.size());
		    	allPart.addAll(allSubPart);
			}
	    }
		    	
    	//初始化传入来的两个参数
    	if(reviewObjs == null)
    		reviewObjs = new WTArrayList();
    	else
    		reviewObjs.clear();
    	reviewObjs.add(doc);
		if(tableData == null)
			tableData = new ArrayList<WTPart>();	
		else
			tableData.clear();
		
			   	    	    
	    //遍历pbo所关联的每一个BOM结构，只处理【原材料】和【半成品】，其它类型均不管
	    for (WTPart onePart : allPart) {	 	    
	    	//如果是【原材料】 或者 【半成品】对象	 时	    	
	    	if(BOMBusinessUtil.isSubObject(onePart, RAWMATERIAL) || BOMBusinessUtil.isSubObject(onePart, SEMIFINISHEDGOOD)){
	    		
	    		//如果生命周期状态为【废弃】，则视为不符合
				LifeCycleManaged lcm = (LifeCycleManaged)onePart;	
				String currentState = lcm.getState().toString();
				out("当前对象【"+onePart.getDisplayIdentifier()+"】的生命周期是："+currentState);
				
				//生命周期状态是【批准、量产发布】，则不处理
				if(currentState.equals("APPROVAL")||currentState.equals("MassProductionRelease"))
					continue;
				
				//OBSOLESCENCE.value=废弃
				if(currentState.equals("OBSOLESCENCE")){
					tableData.add(onePart);
					continue;
				}
	    		
	    		//如果关联了【正在运行的流程】，则视为不符合
				WfProcess runningProcess = null;
				ArrayList<WfProcess> referenceProcessList = BOMBusinessUtil.getRreferenceProcess(onePart);
				//如果不存在任务进程
				if(referenceProcessList != null && referenceProcessList.size() > 0){					
					for (WfProcess process : referenceProcessList) {
						//如果进程正在运行
					    if (process.getState().equals(WfState.OPEN_RUNNING)) {
					    	runningProcess = process;					    	
					    	break;
					    }
					}
				}
				if(runningProcess != null){
					tableData.add(onePart);
					continue;
				}
				//如果没关联【正在运行的流程】
				else{					
					//获取partRecognize属性值
			    	Object recognizeObj = null;
			    	try {
						recognizeObj = IBAUtil.getIBAValue(onePart, "partRecognize");
					} catch (RemoteException e) {
						e.printStackTrace();
					}			    			    	
			    	out("partRecognize属性值为:"+recognizeObj);
			    	if(ComToolUtil.isEmpty(recognizeObj)){
			    		out("partRecognize的值为空，不予处理，直接跳过此次处理！");
			    		continue;
			    	}else{
			    		String flag = recognizeObj.toString().trim();
			    		out("partRecognize的类型是Boolean类型.");
			    		//如果属性值为否
			    		if(flag.equalsIgnoreCase("false") || flag.equalsIgnoreCase("否") || flag.equalsIgnoreCase("N")){
			    			//如果生命周期状态为【新建物料】、【正在工作】，则不符合要求
							if(currentState.equals("NewPart")||currentState.equals("INWORK")){
								tableData.add(onePart);
								continue;
							}
							//如果生命周期状态为【新品】，则符合要求
							if(currentState.equals("NewProduct")){
								reviewObjs.add(onePart);
								continue;
							}										    			
			    		}
			    		//如果属性值为是
			    		else{
			    			//如果生命周期状态为【新建物料】、【正在工作】、【新品】，则不符合要求
							if(currentState.equals("NewPart")||currentState.equals("INWORK")||currentState.equals("NewProduct")){
								tableData.add(onePart);
								continue;
							}							
			    		}			    		
			    	}
			    	
				}	    		
	    	}	    	
	    }
	    
	    
	  //更新tableData的数据至最新版本
	    BOMBusinessUtil.getLatestWTPart(tableData);
	    
		//保存被检出部件的编号
		ArrayList<String> checkoutPartNumberList = new ArrayList<String>();
		if(reviewObjs!=null && reviewObjs.size() > 0){
			for(int i=0;i<reviewObjs.size();++i){
				Object obj = null;
				try {
					obj = reviewObjs.getPersistable(i);
				} catch (WTException e) {
					e.printStackTrace();
					throw new WTException("从随签对象里获取第"+(i+1)+"个值时出错，程序终止！");						
				}
		    	if(obj == null || !(obj instanceof WTPart))
		    		continue;
		    		    	
		    	if(WorkInProgressHelper.isCheckedOut((WTPart)obj)){
				    checkoutPartNumberList.add(((WTPart)obj).getNumber());
				}
			}
		}
	    
	    /*if (!checkoutPartNumberList.isEmpty()) {
	    	String checkoutPart = "";
	    	for(String number : checkoutPartNumberList)
	    		checkoutPart += "\n" + number;
	    	throw new WTException("以下对象编号被检出："+checkoutPart);
	    }*/	 
	    
	}
	
	
	
	
	
    /**YW
     * 【设计转量产提交】活动点击【完成任务】按钮时需满足的条件
     * 只有pbo所关联的所有部件中每一个对象都是【成品】，且不是【试制件】，
     * 且生命周期是【新品】或【试产】状态，才让其通过，否则报错
     * @param obj WTObject，即pbo对象，亦即主业务对象
     * @throws WTException
     */
    public static void completeTasklCondition(WTObject obj) throws WTException {
    	
    	if(obj == null || !(obj instanceof WTDocument)){
    		out("传入进来的对象"+obj+"为空或者不是【WTDocument】类型的对象，直接返回空！");
    		return ;
    	}
    	    		
	    WTDocument doc = (WTDocument) obj;
	    //获取当前文档所关联的所有零部件
	    QueryResult refPartQR = ext.com.core.CoreUtil.getAssociatedParts(doc);
	    String  errorPartNumber = "";
	    while (refPartQR.hasMoreElements()) {
			Object refObj = refPartQR.nextElement();
			if (refObj instanceof WTPart) {
			    WTPart part = (WTPart) refObj;
			    		    
			    //如果【当前部件类型】不是【成品】，则记录错误信息：当前编号
				if (!ExamineAndApproveConfirmBusiness.isSubObject(part, FINISHEDGOOD)&& (!TMTypeUtil.isSemiFinishedGood(part))) {
					errorPartNumber += "\n"+part.getDisplayIdentifier()+"   :   不是【成品】或【半成品】类型!";
					continue;
				}
			
			    //如果当前部件是【试制件】(即编号是以-T结尾),则记录错误信息：当前编号
			    if (part.getNumber().endsWith("-T")) {
			    	errorPartNumber += "\n"+part.getDisplayIdentifier()+"   :  是【试制件】类型!";
			    	continue;			    	
			    }
			    
			    //如果当前部件的生命周期不是【新品】或【试产】或【风险批量】或【小批量】状态，则记录错误信息：当前编号
			    if(!ExamineAndApproveConfirmBusiness.isInner(part, LIFESTATEARRAY)){
			    	errorPartNumber += "\n"+part.getDisplayIdentifier()+"   :   生命周期不是【新品】或【试产】或【风险批量】或【小批量】状态!";
			    	continue;
			    }
			    
			}
	    }
	    
	    if ((getSoftType(doc).contains("cn.tianma.transferProductionMeeting")) && (refPartQR.size() == 0)) {
	        errorPartNumber = errorPartNumber + doc.getDisplayIdentifier() + " : 该设计转量产会议纪要文档没有关联成品!" + "\n";
	      }
	    
	    if(!ComToolUtil.isEmpty(errorPartNumber))
	    	throw new WTException("业务主对象【"+doc.getDisplayIdentifier()+"】所关联的部件中，存在以下不满足要求的对象:"+errorPartNumber);	    		
    }
	
    public static String getSoftType(WTObject obj)
    {
      String result = null;
      try {
        String typePath = ClientTypedUtility.getExternalTypeIdentifier(obj);
        result = typePath.substring(typePath.lastIndexOf("|") + 1);
      } catch (Exception e) {
        e.printStackTrace();
        result = obj.getClass().getName();
      }
      return result;
    }

}
